package ar.com.msebuilder;

import java.io.File;

import org.tmatesoft.svn.core.SVNDepth;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory;
import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
import org.tmatesoft.svn.core.internal.wc.DefaultSVNOptions;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.wc.SVNClientManager;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc.SVNUpdateClient;
import org.tmatesoft.svn.core.wc.SVNWCUtil;

public class SVNManager {

	private SVNURL repositoryUrl;
	private SVNClientManager svnClientManager;
	private SVNRepository svnRepository;
	
	public SVNManager(String url, String username, String password){
		try {
			repositoryUrl = SVNURL.parseURIDecoded(url);
			// Sets up a repository depending on the type of URL given
			if (url.startsWith("svn")){
				SVNRepositoryFactoryImpl.setup();
		        svnRepository = SVNRepositoryFactory.create(repositoryUrl);
			} else { 
				if (url.startsWith("http")) {
					DAVRepositoryFactory.setup();
			        svnRepository = DAVRepositoryFactory.create(repositoryUrl);
				} else {
					if (url.startsWith("file")) {
						FSRepositoryFactory.setup();
				        svnRepository = FSRepositoryFactory.create(repositoryUrl);
					}
				}
			}
			/*
	         * Creates a default run-time configuration options driver. Default options 
	         * created in this way use the Subversion run-time configuration area (for 
	         * instance, on a Windows platform it can be found in the '%APPDATA%\Subversion' 
	         * directory). 
	         * 
	         * readonly = true - not to save  any configuration changes that can be done 
	         * during the program run to a config file (config settings will only 
	         * be read to initialize; to enable changes the readonly flag should be set
	         * to false).
	         * 
	         * SVNWCUtil is a utility class that creates a default options driver.
	         */
	        DefaultSVNOptions options = new DefaultSVNOptions();
	        // Creates an instance of SVNClientManager providing a default auth 
	        // manager and an options driver
	        svnClientManager = SVNClientManager.newInstance(options, username, password);
	        // Set the auth manager for the repository object
	        ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(username, password);
            svnRepository.setAuthenticationManager(authManager);
		} catch (SVNException e) {
			e.printStackTrace();
		}
	}

	/**
	 * @return true if the workspace was downloaded successfully, false if not.
	 * */
	public boolean exportRevision(SVNRevision revision, String destPath) {
		SVNUpdateClient updateClient = svnClientManager.getUpdateClient();
		System.out.println("Exporting revision " + revision.getNumber() + " from '" + 
			repositoryUrl.toString() + "' to '" + destPath + "'...");
		// Sets externals not to be ignored during the checkout
		updateClient.setIgnoreExternals(false);
		// Create the workspace folder if it doesn't exist yet
//		File destFolder = new File(destPath);
//		destFolder.mkdirs();
		try {
			// Export a copy of the given revision
			updateClient.doExport(repositoryUrl, new File(destPath), 
					revision, revision, null, true, SVNDepth.INFINITY);
			return true;
		} catch (SVNException svne) {
			String message = "Error while checking out a working copy for the location '"
					+ repositoryUrl + "'";
			System.err.println(message + (svne != null ? ": " + svne.getMessage() : ""));
			
			// If the exception is that the workspace is locked,
			// then do a cleanup and start the checkout again
//			if (svne.getMessage().split(":")[1].equals("")) {
				//TODO cleanup
				//checkoutRevision(revision, destPath);				
//			}
		}		
		return false;
	}
	
	public SVNRepository getSVNRepository() {
		return svnRepository;
	}
	
}
